package com.zjdiepu.www.interceptor;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import com.alibaba.fastjson.JSON;
import com.zjdiepu.www.base.core.ApiResponse;
import com.zjdiepu.www.base.enums.type.ResultFlagType;
import com.zjdiepu.www.common.consts.SystemConsts;
import com.zjdiepu.www.commpent.handler.TokenHelper;
import com.zjdiepu.www.commpent.handler.TokenUserHelper;

/**
 * 项目名称：diepu-parent-rest <br/> 
 * 类名称：TokenInterceptor <br/>  
 * 类描述：登录验证 <br/>    
 * 创建人：xiongxiaotun <br/> 
 * 创建时间：2017年6月5日 下午3:12:30  <br/>   
 * 修改人：xiongxiaotun <br/> 
 * 修改时间：2017年6月5日 下午3:12:30   <br/>  
 * 修改备注：    <br/> 
 * @version V1.0   <br/>
 */
public class TokenInterceptor extends HandlerInterceptorAdapter {
	
    private static final Logger logger = LoggerFactory.getLogger(TokenInterceptor.class);
	
	@Resource
	private TokenUserHelper tokenUserHelper;

    /**
     * 请求预处理：验证登录信息
     */
    @Override
    @SuppressWarnings("unchecked")
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    	String ip = getIpAddr(request);
        String url = request.getRequestURL().toString();
        String method = request.getMethod();
		Map<String, String[]> params = request.getParameterMap();
        logger.info("{}||||{}||||{}||||{}", ip, url, method, JSON.toJSONString(params));
        request.setAttribute("url_start", System.currentTimeMillis());
        String token = request.getHeader(SystemConsts.HEADER_FOR_TOKEN);
        if(StringUtils.isBlank(token)) {
        	responseOutWithJson(response, ApiResponse.overdue(ResultFlagType.ACCESS_DENIED.getCode(), ResultFlagType.ACCESS_DENIED.getValue()));
        	return false;
        }
        TokenHelper.setToken(token);
        return true;
        
    }
    
    /**
     * 响应：记录处理时间
     */
	@Override
	@SuppressWarnings("unchecked")
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		long finished = System.currentTimeMillis();
		long start = (Long)request.getAttribute("url_start");
		String ip = getIpAddr(request);
        String url = request.getRequestURL().toString();
        String method = request.getMethod();
		Map<String, String[]> params = request.getParameterMap();
		logger.info("{}||||{}||||{}||||{}||||{}", ip, url, method, JSON.toJSONString(params), finished-start);
		tokenUserHelper.exprieToken();
		TokenHelper.clearToken();
	}
	
	/**
     * 
     * 获取客户端IP地址: <br>
     * 
     * @param request
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    private String getIpAddr(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }
    
    /** 
     * 以JSON格式输出 
     * @param response 
     */  
    private void responseOutWithJson(HttpServletResponse response,  
            Object responseObject) { 
    	if(!response.isCommitted()) {
    		response.setCharacterEncoding("UTF-8");  
    		response.setContentType("application/json; charset=utf-8");  
    		PrintWriter out = null;  
    		try {  
    			out = response.getWriter();  
    			out.append(JSON.toJSONString(responseObject));  
    		} catch (IOException e) { 
    			logger.error("验证登录信息发生异常。", e);
    		} finally {  
    			if (out != null) {  
    				out.flush();
    				out.close();  
    			}  
    		}  
    	}
    }  

}
